package net.keebook.webapp.ws;

import java.io.IOException;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;

import net.keebook.webapp.bean.LoginSupportBean;
import net.keebook.webapp.bean.OAuthBean;
import net.keebook.webapp.dao.SettingDao;
import net.keebook.webapp.entity.User;
import net.keebook.webapp.entity.User.LoginMethod;
import net.keebook.webapp.model.SessionModel;
import net.keebook.webapp.util.Messages;
import net.keebook.webapp.util.SettingId;
import net.keebook.webapp.util.oauth.OpenIdCredentials;


@Path("/oauth/{provider}")
@Stateless
public class OAuthService extends WebService {
	@EJB
	private SettingDao settingDao;
	@EJB
	private OAuthBean oAuthBean;
	@EJB
	private LoginSupportBean loginSupportBean;
	
	@GET
	public void verify(@Context HttpServletRequest request, @Context HttpServletResponse response, @PathParam("provider") String provider, @DefaultValue("") @QueryParam("code") String code) throws IOException {
		String root = getSettingDao().get(SettingId.PUBLIC_URL).getValue();
		if (!root.endsWith("/")) {
			root += "/";
		}
		
		HttpSession httpSession = request.getSession(true);
		SessionModel sessionModel = SessionModel.getInstance(httpSession);
		
		OpenIdCredentials credentials = getoAuthBean().verify(provider, code, sessionModel);
		
		if (credentials == null) {
			if (sessionModel.getMigrateAccount()) {
				sessionModel.setMigrateAccount(false);
				response.sendRedirect(root + "migrateaccount.xhtml?msg="+Messages.ACCOUNT_MIGRATION_FAILED);
			} else {
				response.sendRedirect(root + "login.xhtml?msg="+Messages.LOGIN_FAILED);
			}
			return;
		}
		
		User user;
		if (sessionModel.getMigrateAccount()) {
			sessionModel.setMigrateAccount(false);
			User oAuthUser = getUserDao().getUserByOauthId(credentials.getIdentifier());
			user = getUserDao().get(sessionModel.getUserId());
			if (user != null && (oAuthUser == null || oAuthUser.getId() == user.getId())) {
				user.setOauthId(credentials.getIdentifier());
				user.setLoginMethod(LoginMethod.OAUTH);
				getUserDao().update(user);
				response.sendRedirect(root + "migrateaccount.xhtml?msg="+Messages.ACCOUNT_MIGRATED);
			} else {
				response.sendRedirect(root + "migrateaccount.xhtml?msg="+Messages.ACCOUNT_MIGRATION_FAILED);
			}
		} else {
			user = getUserDao().getUserByOauthId(credentials.getIdentifier());
		
			if (user == null) {
				String systemTimeZoneId = getSettingDao().get(SettingId.SYSTEM_TIMEZONE).getValue();
				
				user = new User();
				user.setEmail(credentials.getEmail());
				user.setName(credentials.getName());
				user.setTimezone(systemTimeZoneId);
				user.setOauthId(credentials.getIdentifier());
				user.setLoginMethod(LoginMethod.OAUTH);
				getUserDao().store(user);
			}
			
			getLoginSupportBean().login(user, sessionModel);
			
			response.sendRedirect(root + getLoginSupportBean().getRedirectionUrl(sessionModel));
		}
	}

	public SettingDao getSettingDao() {
		return settingDao;
	}

	public void setSettingDao(SettingDao settingDao) {
		this.settingDao = settingDao;
	}

	public OAuthBean getoAuthBean() {
		return oAuthBean;
	}

	public void setoAuthBean(OAuthBean oAuthBean) {
		this.oAuthBean = oAuthBean;
	}

	public LoginSupportBean getLoginSupportBean() {
		return loginSupportBean;
	}

	public void setLoginSupportBean(LoginSupportBean loginSupportBean) {
		this.loginSupportBean = loginSupportBean;
	}
}
